/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.search.strategy;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import net.groupme.model.Group;
import net.groupme.model.ObjectFactory;
import net.groupme.model.Resource;
import net.groupme.model.Tag;
import net.groupme.utils.sql.SelectQueryUtility;

/**
 * created on 9 Jan 2008
 * 
 * This class implements a simple search strategy, which returns all resources, which
 * are relevant to a given tag. "relevant for a tag t" means:
 * <ol>
 * 	<li>resource is directly tagged with t</li>
 * 	<li>resource is contained in a group, which is tagged with t</li>
 *  <li>resource is contained in a group, which contains resources that are tagged with t</li>
 * </ol>
 * The search strategy does not rank the resources.
 * 
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.4 $ $Date: 2008-05-30 01:19:37 $
 */
public class SearchAndReturnEverythingThatIsRelatedUnranked implements SearchStrategy{
	
	private boolean includePopularResources = false;

	/**
	 * Creates a new SearchAndReturnEverythingThatIsRelatedUnranked instance. 
	 */
	public SearchAndReturnEverythingThatIsRelatedUnranked() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * Creates a new SearchAndReturnEverythingThatIsRelatedUnranked instance.
	 * @param includePopularResources 
	 */
	public SearchAndReturnEverythingThatIsRelatedUnranked(
			boolean includePopularResources) {
		super();
		this.includePopularResources = includePopularResources;
	}

	/* (non-Javadoc)
	 * @see net.groupme.search.strategy.SearchStrategy#searchForGroups(java.util.Collection, boolean)
	 */
	public List<Group> searchForGroups(Collection<Tag> tags, boolean allTags) {
		String query = "";
		String keyword = "";
		Statement sqlStatement = null;
		ResultSet result = null;
		List<Group> relatedUnrankedGroups = new ArrayList<Group>();
		for(Tag tag: tags){
			keyword = tag.getKeyword();
			query = "select distinct  id from Resource where type = 'group'" +
			//directly tagged:
			"id in  (Select resourceId from userTagGroupResource as tas, Tag as t WHERE tas.tagId = t.id AND t.keyword = '" + keyword + "') OR  " +
			//groups inherit their tags:
			"id in (Select gr.resourceId from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.groupId = tas.resourceId AND tas.tagId = t.id AND t.keyword = '" + keyword + "') OR " +
			//resources inherit their tags:
			"id in  (Select gr.resourceId from groupResource as gr where gr.groupId in  ( select gr.groupId from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.resourceId = tas.resourceId AND tas.tagId = t.id AND t.keyword = '" + keyword + "'))";
			
			try {
				sqlStatement = ObjectFactory.ds.getConnection().createStatement();
				result = sqlStatement.executeQuery(query);
				while (result.next()) {
					relatedUnrankedGroups.add(ObjectFactory.getGroup(result.getString(1)));
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return relatedUnrankedGroups;
	}

	/* (non-Javadoc)
	 * @see net.groupme.search.strategy.SearchStrategy#searchForResources(java.util.Collection, boolean, boolean)
	 */
	public List<Resource> searchForResources(Collection<Tag> tags, boolean allTags, boolean noGroups) {
		String query = "";
		String keyword = "";
		Statement sqlStatement = null;
		ResultSet result = null;
		List<Resource> relatedUnrankedResources = new ArrayList<Resource>();
		for(Tag tag: tags){
			keyword = tag.getKeyword();
			query = "select distinct  id, name, description, url, type from Resource where " +
			//directly tagged:
			"id in  (Select resourceId from userTagGroupResource as tas, Tag as t WHERE tas.tagId = t.id AND t.keyword = '" + keyword + "') OR  " +
			//groups inherit their tags:
			"id in (Select gr.resourceId from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.groupId = tas.resourceId AND tas.tagId = t.id AND t.keyword = '" + keyword + "') OR " +
			//resources inherit their tags:
			"id in  (Select gr.resourceId from groupResource as gr where gr.groupId in  ( select gr.groupId from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.resourceId = tas.resourceId AND tas.tagId = t.id AND t.keyword = '" + keyword + "'))";
			
			try {
				sqlStatement = ObjectFactory.ds.getConnection().createStatement();
				result = sqlStatement.executeQuery(query);
				while (result.next()) {
					relatedUnrankedResources.add(ObjectFactory.getInMemoryResource(result.getString(1), result.getString(2), result.getString(3), result.getURL(4), result.getString(5)));
				}
				//for CIKM analysis:
				if(includePopularResources){
					result = SelectQueryUtility.executeQuery("select distinct  r.id, r.name, r.description, r.url, r.type from Resource as r, (Select count(*) as num, resourceId from userTagGroupResource group by resourceId order by num desc) as tas where r.timeAndDate < '2008-01-16' AND tas.resourceId = r.id order by tas.num desc limit 20");
					while (result.next()) {
						Resource actualResource = ObjectFactory.getInMemoryResource(result.getString(1), result.getString(2), result.getString(3), result.getURL(4), result.getString(5));
						if(!relatedUnrankedResources.contains(actualResource)){
							relatedUnrankedResources.add(actualResource);
						}
					}
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		Collections.shuffle(relatedUnrankedResources);
		return relatedUnrankedResources;
	}
/*
 select distinct  * from Resource where ( id in  (Select resourceId from userTagGroupResource as tas, Tag as t WHERE tas.tagId = t.id AND t.keyword = 'semantic web') OR  id in (Select gr.resourceId from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.groupId = tas.resourceId AND tas.tagId = t.id AND t.keyword = 'semantic web') OR id in  (Select gr.resourceId from groupResource as gr, ( select gr.groupId as idB from groupResource as gr, userTagGroupResource as tas, Tag as t where gr.resourceId = tas.resourceId AND tas.tagId = t.id AND t.keyword = 'semantic web') as b where b.idB = gr.resourceId ) 
 ) AND timeAndDate < '2008-01-16' group by id 
 */
}
